home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-I386 / SEMAPHOR.{2E < prev    next >
Text File  |  1999-09-17  |  2KB  |  95 lines

  1. #ifndef _I386_SEMAPHORE_HELPER_H
  2. #define _I386_SEMAPHORE_HELPER_H
  3.  
  4. /*
  5.  * SMP- and interrupt-safe semaphores helper functions.
  6.  *
  7.  * (C) Copyright 1996 Linus Torvalds
  8.  * (C) Copyright 1999 Andrea Arcangeli
  9.  */
  10.  
  11. /*
  12.  * These two _must_ execute atomically wrt each other.
  13.  *
  14.  * This is trivially done with load_locked/store_cond,
  15.  * but on the x86 we need an external synchronizer.
  16.  */
  17. static inline void wake_one_more(struct semaphore * sem)
  18. {
  19.     unsigned long flags;
  20.  
  21.     spin_lock_irqsave(&semaphore_wake_lock, flags);
  22.     if (atomic_read(&sem->count) <= 0)
  23.         sem->waking++;
  24.     spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  25. }
  26.  
  27. static inline int waking_non_zero(struct semaphore *sem)
  28. {
  29.     unsigned long flags;
  30.     int ret = 0;
  31.  
  32.     spin_lock_irqsave(&semaphore_wake_lock, flags);
  33.     if (sem->waking > 0) {
  34.         sem->waking--;
  35.         ret = 1;
  36.     }
  37.     spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  38.     return ret;
  39. }
  40.  
  41. /*
  42.  * waking_non_zero_interruptible:
  43.  *    1    got the lock
  44.  *    0    go to sleep
  45.  *    -EINTR    interrupted
  46.  *
  47.  * We must undo the sem->count down_interruptible() increment while we are
  48.  * protected by the spinlock in order to make atomic this atomic_inc() with the
  49.  * atomic_read() in wake_one_more(), otherwise we can race. -arca
  50.  */
  51. static inline int waking_non_zero_interruptible(struct semaphore *sem,
  52.                         struct task_struct *tsk)
  53. {
  54.     unsigned long flags;
  55.     int ret = 0;
  56.  
  57.     spin_lock_irqsave(&semaphore_wake_lock, flags);
  58.     if (sem->waking > 0) {
  59.         sem->waking--;
  60.         ret = 1;
  61.     } else if (signal_pending(tsk)) {
  62.         atomic_inc(&sem->count);
  63.         ret = -EINTR;
  64.     }
  65.     spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  66.     return ret;
  67. }
  68.  
  69. /*
  70.  * waking_non_zero_trylock:
  71.  *    1    failed to lock
  72.  *    0    got the lock
  73.  *
  74.  * We must undo the sem->count down_trylock() increment while we are
  75.  * protected by the spinlock in order to make atomic this atomic_inc() with the
  76.  * atomic_read() in wake_one_more(), otherwise we can race. -arca
  77.  */
  78. static inline int waking_non_zero_trylock(struct semaphore *sem)
  79. {
  80.     unsigned long flags;
  81.     int ret = 1;
  82.  
  83.     spin_lock_irqsave(&semaphore_wake_lock, flags);
  84.     if (sem->waking <= 0)
  85.         atomic_inc(&sem->count);
  86.     else {
  87.         sem->waking--;
  88.         ret = 0;
  89.     }
  90.     spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  91.     return ret;
  92. }
  93.  
  94. #endif
  95.